package qc.module.qms.service.producer;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.constants.QmsMQConstant;
import qc.common.core.enums.qms.QmsPointDataQualityEnum;
import qc.common.core.enums.qms.QmsPointTimeSegmentEnum;
import qc.module.qms.dto.mq.QmsMqPointDataMessageDto;
import qc.module.qms.service.log.QmsLogPointDataService;

/**
 * QMS点号数据发送至MQ生产者Producer，只管发送消息，不管消息是否发送至MQ
 *
 * @author QuCheng Tech
 * @since 2025/8/19
 */
@Service
public class QmsPointDataProducer {
    private static final Logger logger = LoggerFactory.getLogger(QmsPointDataProducer.class);

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 消息队列中点号数据主题名称
     */
    private static final String MQ_PointData_Topic = QmsMQConstant.MQ_POINTDATA_TOPIC;

    @Autowired
    private QmsLogPointDataService logPointDataService;

    /**
     * 向消息队列中发送点号数据消息
     * 发送消息不返回结果，发送错误或异常也不报错
     *
     * @param message 消息对象
     * @return java.lang.String
     * @author QuCheng Tech
     * @since 2025/10/5
     */
    public void send(QmsMqPointDataMessageDto message) {
        try {
            logger.debug("syncSend", message);

            //在此对传入的消息对象进行有效性验证，验证不通过的不发送至MQ，在消息的消费者中不需要进行判断
            //接收到的消息有效性验证：点号数据消息中的点号、时段类型、起止时间必须有效；实际受影响数据集合可以为空（在人工进行删除、标记为可疑或正常数据时）
            String validMessageResult = null;
            if (message == null) {
                validMessageResult = "点号数据消息对象为空";
            } else {
                if (StringUtils.isBlank(message.getPointid()))
                    validMessageResult += "点号数据消息对象中点号编码为空，";
                if (message.getTmseg() == QmsPointTimeSegmentEnum.UN_DEFINE)
                    validMessageResult += "点号数据消息对象中点号时段类型无效，";
                if (message.isManual() == true) {
                    //人工操作时，数据质量为正常数据表示人工进行数据录入或修改
                    //人工操作时，数据质量为删除、错误或人工数据时表示人工进行数据质量设置
                    if (message.getQuality() != QmsPointDataQualityEnum.NORMAL && message.getQuality() != QmsPointDataQualityEnum.DELETE && message.getQuality() != QmsPointDataQualityEnum.ERROR && message.getQuality() != QmsPointDataQualityEnum.MANUAL)
                        validMessageResult += "点号数据消息对象中为人工操作时数据质量设置错误，";
                }
                if (message.getBeginTime() == null)
                    validMessageResult += "点号数据消息对象中起始数据时标不能为空，";
                if (message.getEndTime() == null)
                    validMessageResult += "点号数据消息对象中截止数据时标不能为空，";
                if (message.getBeginTime() != null && message.getEndTime() != null && message.getBeginTime().isAfter(message.getEndTime()) == true)
                    validMessageResult += "点号数据消息对象中数据时标错误，起始数据时标不能大于截止数据时标，";
                //受影响的数据记录可以为空，不需要判断
            }
            //判断如果接收到的消息有效性验证未通过，进行错误日志记录
            if (StringUtils.isNotBlank(validMessageResult)) {
                logger.warn("发送点号数据至MQ失败，" + validMessageResult);
            } else {
                SendResult sendResult = rocketMQTemplate.syncSend(MQ_PointData_Topic, message);
                SendStatus sendStatus = sendResult.getSendStatus();
                //根据发送至消息队列的结果进行判断，如果发送成功则返回成功（后续的数据处理和保存至数据库均由对应消费者进行），如果发送失败则需要再次直接调用保存到原始数据库方法
                if (sendStatus == SendStatus.SEND_OK) {
                    //发送成功，此处不需要做任何处理，在消息消费者中进行点号数据日志保存至数据库操作
                } else {
                    //发送失败，直接将点号数据消息写入到数据库中
                    logPointDataService.add(message, false);
                }
            }
        } catch (Exception ex) {
            logger.error("发送点号数据至MQ异常，" + ex.getMessage());
        }
    }
}
